/**
 * @Description: canvas 简单的水印工具
 * @Author: CcSimple
 * @Github: https://github.com/CcSimple
 */
/**
 * @Description: 时间格式化
 * @param date
 * @param format
 * @returns {string|null}
 */
function timeFormat(date, format = 'YYYY-MM-DD') {
	if (!date) return null;
	if (typeof date === 'number') {
		date = new Date(date);
	}
	const year = date.getFullYear();
	const month = date.getMonth();
	const day = date.getDate();
	const hours24 = date.getHours();
	const hours = hours24 % 12 === 0 ? 12 : hours24 % 12;
	const minutes = date.getMinutes();
	const seconds = date.getSeconds();
	const dd = t => `0${ t }`.slice(-2);
	const map = {
		YYYY: year,
		MM: dd(month + 1),
		MMMM: `${ month + 1 }月`,
		M: month + 1,
		DD: dd(day),
		D: day,
		HH: dd(hours24),
		H: hours24,
		hh: dd(hours),
		h: hours,
		mm: dd(minutes),
		m: minutes,
		ss: dd(seconds),
		s: seconds
	};
	return format.replace(/Y+|M+|D+|H+|h+|m+|s+|S+|Q/g, str => String(map[str]));
}

// 水印参数
const defaultOption = {
	id: 'watermark', // 水印id
	watch: false,
	content: 'vue-plugin-hiprint', // 水印内容
	container: '.hiprint-printPaper', // 水印容器
	width: 200, // 水印宽度
	height: 200, // 水印高度
	textAlign: 'center', // 水印文字水平对齐方式
	textBaseline: 'middle', // 水印文字垂直对齐方式
	fontSize: '14px', // 水印文字大小
	fontFamily: 'Microsoft Yahei', // 水印文字字体
	fillStyle: 'rgba(184, 184, 184, 0.3)', // 水印文字颜色
	rotate: 25,// 水印文字旋转角度
	timestamp: false, // 是否显示时间戳
	format: 'YYYY-MM-DD HH:mm', // 时间戳格式
	zIndex: 0
};
// 监听器
let observerMap = {};

/**
 * @Description: 创建水印
 * @param param
 * @private
 */
function _createWatermark(param) {
	const {
		id,
		watch,
		content,
		container,
		width,
		height,
		textAlign,
		textBaseline,
		fontSize,
		fontFamily,
		fillStyle,
		rotate,
		timestamp,
		format,
		zIndex
	} = param;
	observerMap[id] = {
		wmMo: null, // MutationObserver
		wmTimer: null // timestamp
	}
	const canvas = document.createElement('canvas');
	canvas.setAttribute('width', `${ width }px`);
	canvas.setAttribute('height', `${ height }px`);
	let containerDom = typeof container === 'string' ? document.querySelector(container) : container;
	const ctx = canvas.getContext('2d');
	ctx.textAlign = textAlign;
	ctx.textBaseline = textBaseline;
	ctx.font = `${ fontSize } ${ fontFamily }`;
	ctx.fillStyle = fillStyle;
	ctx.translate(width / 2, height / 2);
	ctx.rotate(-(Math.PI / 180) * rotate);
	ctx.fillText(`${ content }`, 0, 0);
	timestamp && ctx.fillText(`${ timeFormat(new Date(), format) }`, 0, parseInt(fontSize) + 5);
	let __vm = containerDom.querySelector('.__vm__' + id);
	const watermarkDiv = __vm || document.createElement('div');
	const withHeightStr = containerDom.getAttribute('style');
	const styleStr = `position:absolute;user-select:none;top:0;left:0;${ withHeightStr };z-index:${ zIndex };pointer-events:none !important;background-repeat:repeat;background-image:url('${ canvas.toDataURL() }')`;
	watermarkDiv.setAttribute('style', styleStr);
	watermarkDiv.classList.add('__vm__' + id);
	if (!__vm) {
		containerDom.insertBefore(watermarkDiv, containerDom.firstChild);
	}
	if (watch) {
		const MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
		if (MutationObserver) {
			observerMap[id]["wmMo"] = new MutationObserver((e) => {
				let change = e.some(item => item.target.className == containerDom.className && item.type == 'attributes');
				__vm = containerDom.querySelector('.__vm__' + id);
				if ((__vm && __vm.getAttribute('style') !== styleStr) || !__vm || change) {
					// 避免一直触发
					observerMap[id]["wmMo"].disconnect();
					observerMap[id]["wmMo"] = null;
					delete observerMap[id]["wmMo"];
					_createWatermark(param);
				}
			});
			observerMap[id]["wmMo"].observe(containerDom, {
				attributes: true, subtree: true, childList: true
			});
		}
	}
	if (format) {
		let timeout = 1000 * 60 * 60 * 24;
		if (format.includes('s')) {
			timeout = 1000;
		} else if (format.includes('m')) {
			timeout = 1000 * 60;
		} else if (format.includes('h') || format.includes('H')) {
			timeout = 1000 * 60 * 60;
		}
		observerMap[id]["wmTimer"] = window.setTimeout(() => {
			// 触发 MutationObserver
			watermarkDiv.style.bottom = '0';
		}, timeout);
	}
}

/**
 * @Description: 销毁水印
 */
const destroyWatermark = function (options) {
	const {
		id,
		watch,
		container,
	} = options;
	if (watch) {
		let containerDom = typeof container === 'string' ? document.querySelector(container) : container;
		// 监听器关闭
		if (observerMap[id]) {
			observerMap[id]["wmMo"] && observerMap[id]["wmMo"].disconnect();
			observerMap[id]["wmMo"] = null;
			observerMap[id]["wmTimer"] && window.clearTimeout(observerMap[id]["wmTimer"]);
			observerMap[id]["wmTimer"] = null;
			delete observerMap[id];
		}
		// 删除水印元素
		const __vm = containerDom.querySelector('.__vm__' + id);
		__vm && __vm.parentNode.removeChild(__vm);
	}
}
/**
 * @Description: 创建水印
 * @param option
 */
const createWatermark = function (option) {
	let options = Object.assign({}, defaultOption, option);
	destroyWatermark(options);
	_createWatermark(options);
}
// 暴露接口
export default {
	createWatermark, destroyWatermark
}